package com.wyz.calibur.infrastructure.config.security;

import cn.hutool.crypto.SecureUtil;
import com.wyz.calibur.enums.RedisKeyEnum;
import com.wyz.calibur.infrastructure.utils.AuthenticationUtil;
import com.wyz.calibur.infrastructure.utils.ContextUtil;
import com.wyz.calibur.infrastructure.utils.JWTTokenUtil;
import com.wyz.calibur.infrastructure.utils.RedisUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.logout.LogoutHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @Description: 退出成功
 * @Author: wei yz
 * @Date: 2022/6/23 14:11
 */
public class CliburLogoutHandler implements LogoutHandler {
    private static final Logger log = LoggerFactory.getLogger(CliburLogoutHandler.class);

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private AuthenticationUtil authenticationUtil;

    @Override
    public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
        log.info("===========退出成功===========");
        String token = ContextUtil.getToken(request);
        if (StringUtils.isNotBlank(token)) {
            // 获取登录的用户信息
            String jwtUsername = (String) redisUtil.get(RedisKeyEnum.AUTH_TOKEN.getKey() + token);
            if (StringUtils.isNotEmpty(jwtUsername)) {
                try {
                    String username = JWTTokenUtil.getSub(jwtUsername);
                    log.info("==> 当前用户：【{}】", username);
                    // 验证是否已经登录过：查询登录凭证获得tokenKey
                    String voucherKey = RedisKeyEnum.LOGIN_VOUCHER.getKey() + SecureUtil.md5(username);
                    String tokenKey = (String) redisUtil.get(voucherKey);
                    authenticationUtil.delTokenInfo(tokenKey, voucherKey);
                    // 清除上下文
                    SecurityContextHolder.clearContext();
                    log.info("=========清除上下文成功=========");
                } catch (Exception e) {
                    log.error("==> JWT 解析异常：[ {} ]", e.getMessage());
                }
            }
        }

    }

}
